#include "polarGraphs.h"


void hrm_data::computeStatistics()
{
	int boundMin=session->user_hr_rest;
	int boundMax=session->user_hr_max;

	//boundmin is unused!!
	int nbp=0;
	int wrongpoints=0;
	float energy=0;
	
	statsAll.HRmin=1000;statsAll.HRmax=0;statsAll.HRAverage=0;
	statsAll.speedMin=1000;statsAll.speedMax=0;statsAll.speedAverage=0;
	statsAll.energy=0;

	statsSelection.HRmin=1000;statsSelection.HRmax=0;statsSelection.HRAverage=0;
	statsSelection.speedMin=1000;statsSelection.speedMax=0;statsSelection.speedAverage=0;
	statsSelection.energy=0;

	float hfact=(float)boundMax/nbbins;
	for (unsigned int i=0;i<nbbins;i++) histogram[i]=0;
	statsAll.duration=session->number_of_samples*session->recording_interval;
	statsSelection.duration=0;

	//compute global stats
	for (unsigned int j=0;j<session->number_of_samples;j++)
	{
		unsigned int position = (unsigned int)(session->sample[j].hr/hfact);
		if (position<nbbins)
		{
			histogram[position]+=1;
			float pc=(float)session->sample[j].hr/session->user_hr_max;
			statsAll.energy+=compute_Kcal(pc,session->user_weight,session->user_vo2_max)*session->recording_interval;
			
			if (session->sample[j].hr>statsAll.HRmax) statsAll.HRmax=session->sample[j].hr;
			if (session->sample[j].hr<statsAll.HRmin) statsAll.HRmin=session->sample[j].hr;
			statsAll.HRAverage+=session->sample[j].hr;
		}
		else wrongpoints+=1;
	}
	nbp=session->number_of_samples-wrongpoints;
	statsAll.HRAverage/=nbp;

	
//compute selections stats
	if (session->selections.size()!=0)
	{
		nbp=0;
		for (unsigned int i=0;i<nbbins;i++) histogram[i]=0;
		for (unsigned int i=0;i<session->selections.size();i++)
		{
			unsigned int nbpoints = session->selections[i].high-session->selections[i].low+1;
			unsigned int duration = nbpoints*session->recording_interval;
			statsSelection.duration+=duration;
			nbp+=nbpoints;
			for (unsigned int j=session->selections[i].low;j<session->selections[i].high;j++)
			{
				unsigned int position = (unsigned int)(session->sample[j].hr/hfact);
				if (position<nbbins)
				{
					histogram[position]+=1;
					if (session->sample[j].hr>statsSelection.HRmax) statsSelection.HRmax=session->sample[j].hr;
					if (session->sample[j].hr<statsSelection.HRmin) statsSelection.HRmin=session->sample[j].hr;
					statsSelection.HRAverage+=session->sample[j].hr;
				
					float pc=(float)session->sample[j].hr/session->user_hr_max;
					statsSelection.energy+=compute_Kcal(pc,session->user_weight,session->user_vo2_max)*session->recording_interval;
				}
				else wrongpoints+=1;
			}
		}
		nbp-=wrongpoints;
		statsSelection.HRAverage/=nbp;
	}

	if (statsSelection.energy==0) energy=statsAll.energy;
	else energy=statsSelection.energy;
	
	//update pdd content:
	int posPDD=exNumberForToday;
	if (posPDD!=-1)
	{
		int interv = session->recording_interval;
		pddContent->exerciseinfo[posPDD].zone9Time=(histogram[0]+histogram[1])*interv;
		pddContent->exerciseinfo[posPDD].zone8Time=(histogram[2]+histogram[3])*interv;
		pddContent->exerciseinfo[posPDD].zone7Time=(histogram[4]+histogram[5])*interv;
		pddContent->exerciseinfo[posPDD].zone6Time=(histogram[6]+histogram[7])*interv;
		pddContent->exerciseinfo[posPDD].zone5Time=(histogram[8]+histogram[9])*interv;
		pddContent->exerciseinfo[posPDD].zone4Time=(histogram[10]+histogram[11])*interv;
		pddContent->exerciseinfo[posPDD].zone3Time=(histogram[12]+histogram[13])*interv;
		pddContent->exerciseinfo[posPDD].zone2Time=(histogram[14]+histogram[15])*interv;
		pddContent->exerciseinfo[posPDD].zone1Time=(histogram[16]+histogram[17])*interv;
		pddContent->exerciseinfo[posPDD].zone0Time=(histogram[18]+histogram[19])*interv;
		pddContent->exerciseinfo[posPDD].totalTime=nbp*interv;
		pddContent->exerciseinfo[posPDD].energy=(int)energy;
		
		for (unsigned int i=0;i<nbbins;i++) histogram[i]/=(float)nbp;
	}
}


void hrm_data::saveDATA()
{
	//save changes
	if (session->sample.size()!=0 && has_changed==1)
	{
		switch( QMessageBox::question( NULL, "",
        QObject::tr("Selections have changed.\n"
        "Save new selections?"),
        QObject::tr("Yes"),
        QObject::tr("No"), 0, 0, 1 ) ) {
    case 0: // The user clicked the Retry again button or pressed Enter
			_saveHRM(session->filename.c_str(),*session);
			_savePDD(pddContent->filename.c_str(),*pddContent);
			has_changed=0;
        break;
    case 1: // The user clicked the Quit or pressed Escape
        // exit
        break;
    }
	}
}


int hrm_data::loadDATA(std::string path,QDate const &thedate,int exnumber)
{
	//generate hrm name for that date
	session->filename = path+buildHRMfilename(thedate.year()-2000,thedate.month(),thedate.day(),exnumber);

	int intStat = checkFileExistence(session->filename.c_str()); 
	if (intStat!=0) return -1;
	int res = _readHRM(session->filename.c_str(),*session);
	if (res==-1) return -1;


	//generate pdd filename for that date
	pddContent->filename=path+buildPDDfilename(session->year,session->month,session->day);
	
	int status=_readPDD(pddContent->filename.c_str(),*pddContent);
	//if status==-1, the file is corrupted and needs to be repaired
	if (status==-1) {std::cout<<"the pdd file is damaged"<<std::endl;return -1;}

	exNumberForToday=exnumber-1;
	
	if (status==0)
	{
		unsigned int starttime=session->start_hour*3600+session->start_minute*60+session->start_second;

		for (unsigned int j=0;j<pddContent->dayinfo.nbrExercises;j++) //check if this session exists in pdd
		{
			if (starttime==pddContent->exerciseinfo[j].startTime) //exercise exists
			{
				exNumberForToday=j;
				break;
			}
		}
	}
	//compute necessary data for plotting
	computeStatistics();
	return 0;
}




float gimmeStep(float range, int targetSteps)
{
	float tempStep = range/targetSteps;
	float mag = floor(log10(tempStep)); 
	float magPow = (float)pow(10, mag); 
// calculate most significant digit of the new step size 
	float magMsd = (int)(tempStep/magPow + 0.5); 
	// promote the MSD to either 1, 2, or 5
	if (magMsd > 50.0) magMsd = 100.0f; 
	else if (magMsd > 20.0) magMsd = 50.0f; 
	else if (magMsd > 10.0) magMsd = 20.0f; 
	else if (magMsd > 5.0) magMsd = 10.0f; 
	else if (magMsd > 2.0) magMsd = 5.0f; 
	else if (magMsd > 1.0) magMsd = 2.0f; 
	return magMsd*magPow;
}


float gimmeStepTime(float range, int targetSteps)
{
	float tempStep = range/targetSteps;
	float mag = floor(log10(tempStep)/log10(60)); 
	float magPow = (float)pow(60, mag); 
// calculate most significant digit of the new step size 
	float magMsd = (int)(tempStep/magPow + 0.5); 
	// promote the MSD to either 1, 2, or 5
	if (magMsd > 30.0) magMsd = 60.0f; 
	else if (magMsd > 20.0) magMsd = 30.0f; 
	else if (magMsd > 10.0) magMsd = 20.0f; 
	else if (magMsd > 5.0) magMsd = 10.0f; 
	else if (magMsd > 2.0) magMsd = 5.0f; 
	else if (magMsd > 1.0) magMsd = 2.0f; 
	return magMsd*magPow;
}

QString graph::step2hms(float step)
{
	int valhour,valmin,valsecond;
	valhour = step/3600;
	valmin = (step-3600*valhour)/60;
	valsecond = step - 3600*valhour - 60*valmin;

	QString disp = QString::number(valhour)+":"+QString::number(valmin)+":"+QString::number(valsecond);
	return disp;
}

void checkBounds(float &val,float minimum, float maximum)
{
	if (val<minimum) val=minimum;
	if (val>maximum) val=maximum;
}

void graph::initializeAxesScales()
{
	FCminDisplay=default_graph_configuration->FCminDisplay;
	FCmaxDisplay=default_graph_configuration->FCmaxDisplay;
	SPEEDminDisplay=default_graph_configuration->SPEEDminDisplay;
	SPEEDmaxDisplay=default_graph_configuration->SPEEDmaxDisplay;
	user_hr_rest=default_graph_configuration->user_hr_rest;
	user_hr_max=default_graph_configuration->user_hr_max;
	sportzone=&default_graph_configuration->sportzones[0];
}


void graph::drawAxisLeft(QString Legend, QColor LegendColor, int AxisType, float minDisplay, float maxDisplay)
{
	int dynamic = maxDisplay-minDisplay;
	QGraphicsTextItem * ttt = scene->addText( Legend,box.myfont );
	ttt -> setPos(box.GRAPHOX-30*box.ratio2normal,box.GRAPHOY-30*box.ratio2normal);
	ttt -> setDefaultTextColor(LegendColor);

	int nbstepsV = 10;
	float stepsizeV;
	if (AxisType==BASE10AXIS) stepsizeV = gimmeStep(dynamic,nbstepsV);
	else stepsizeV = gimmeStepTime(dynamic,nbstepsV);

	gPen.setColor(Qt::black);
	
//top to bottom
/*
	int i=0;
	while (maxDisplay-i*stepsizeV>minDisplay)
	{
		scene->addLine(-3,i*stepsizeV/dynamic*box.GRAPHHEIGHT,3,i*stepsizeV/dynamic*box.GRAPHHEIGHT,gPen)->moveBy(box.GRAPHOX,box.GRAPHOY);

		QString toDisp;
		if (AxisType==BASE10AXIS) toDisp=QString::number(maxDisplay-i*stepsizeV);
		else toDisp=step2hms(maxDisplay-i*stepsizeV);
		QGraphicsTextItem * ttt = scene->addText( toDisp,box.myfont );
		ttt -> setPos(box.GRAPHOX-33*box.ratio2normal,i*stepsizeV/dynamic*box.GRAPHHEIGHT+box.GRAPHOY-12*box.ratio2normal);
		ttt -> setDefaultTextColor(LegendColor);
		i++;
	}
*/

//bottom to top
{
	int i=0;
	gPen.setColor(Qt::black);
	while (minDisplay+i*stepsizeV<=maxDisplay && i<=2*nbstepsV)
	{
		scene->addLine(box.GRAPHOX-3,box.GRAPHHEIGHT-i*stepsizeV/dynamic*box.GRAPHHEIGHT+box.GRAPHOY,
									 box.GRAPHOX+3,box.GRAPHHEIGHT-i*stepsizeV/dynamic*box.GRAPHHEIGHT+box.GRAPHOY,gPen);
		QString toDisp;
		if (AxisType==BASE10AXIS) toDisp=QString::number(minDisplay+i*stepsizeV);
		else toDisp=step2hms(minDisplay+i*stepsizeV);
		QGraphicsTextItem * ttt = scene->addText( toDisp,box.myfont );
		ttt-> setPos(box.GRAPHOX-33*box.ratio2normal,box.GRAPHOY+box.GRAPHHEIGHT-i*stepsizeV/dynamic*box.GRAPHHEIGHT-12*box.ratio2normal);
		ttt -> setDefaultTextColor(LegendColor);
		i++;
	}
}

}


void graph::drawAxisRight(QString Legend, QColor LegendColor, int AxisType, float minDisplay, float maxDisplay)
{
	int dynamic = maxDisplay-minDisplay;

	QGraphicsTextItem * ttt = scene->addText(Legend,box.myfont );
	float width = ttt->boundingRect().width();
	ttt -> setPos(box.THUMBWIDTH-width-10,box.GRAPHOY-30*box.ratio2normal);
	ttt -> setDefaultTextColor(LegendColor);

	int nbstepsV = 10;
	float stepsizeV;
	if (AxisType==BASE10AXIS) stepsizeV = gimmeStep(dynamic,nbstepsV);
	else stepsizeV = gimmeStepTime(dynamic,nbstepsV);
	
{
	int i=0;
	gPen.setColor(Qt::black);
	while (minDisplay+i*stepsizeV<maxDisplay && i<=2*nbstepsV)
	{
		scene->addLine(box.GRAPHOX+box.GRAPHWIDTH-3,box.GRAPHHEIGHT-i*stepsizeV/dynamic*box.GRAPHHEIGHT+box.GRAPHOY,
									 box.GRAPHOX+box.GRAPHWIDTH+3,box.GRAPHHEIGHT-i*stepsizeV/dynamic*box.GRAPHHEIGHT+box.GRAPHOY,gPen);
		QString toDisp;
		if (AxisType==BASE10AXIS) toDisp=QString::number(minDisplay+i*stepsizeV);
		else toDisp=step2hms(minDisplay+i*stepsizeV);
		QGraphicsTextItem * ttt = scene->addText( toDisp,box.myfont );
		ttt-> setPos(box.GRAPHOX+box.GRAPHWIDTH+3,box.GRAPHOY+box.GRAPHHEIGHT-i*stepsizeV/dynamic*box.GRAPHHEIGHT-12*box.ratio2normal);
		ttt -> setDefaultTextColor(LegendColor);
		i++;
	}
}

}

void graph::drawAxisBottom(QString Legend, QColor LegendColor,int AxisType, float min, float max)
{
	int nbstepsH = 10;
  int range=max-min;
	//int valhour,valmin,valsecond;
	QString Disp;

	float steptime;
	if (AxisType==BASE10AXIS) steptime = gimmeStep(range,nbstepsH);
	else steptime = gimmeStepTime(range,nbstepsH);
{
//draw horizontal axis
	QGraphicsTextItem * ttt = scene->addText( Legend,box.myfont );
	ttt -> setPos(box.GRAPHWIDTH+10*box.ratio2normal+box.GRAPHOX,box.GRAPHHEIGHT-10*box.ratio2normal+box.GRAPHOY);
	ttt -> setDefaultTextColor(LegendColor);
	
	int i=0;
	while (i*steptime<range && i<=2*nbstepsH)
	{
		scene->addLine(i*steptime/range*box.GRAPHWIDTH,box.GRAPHHEIGHT-3,i*steptime/range*box.GRAPHWIDTH,box.GRAPHHEIGHT+3)->moveBy(box.GRAPHOX,box.GRAPHOY);
		
		if (AxisType==BASE10AXIS) Disp=QString::number(min+i*steptime);
		else Disp=step2hms(min+i*steptime);

		scene->addText( Disp,box.myfont ) -> setPos(i*steptime/range*box.GRAPHWIDTH+box.GRAPHOX,box.GRAPHHEIGHT+10*box.ratio2normal+box.GRAPHOY);
		i++;
	}
}
}

void graph::draw1sportzone(QPainter &painter,
													 const int &sportzoneMax,const int &sportzoneMin,const QColor &SPcolor, 
													 int &sumpix,const int &dynamic,
													 const QString legend,const int &fontsize)
{
	QRectF rectangle(0,sumpix,0,0);
	int nbpix;
	int pos1,pos2;

	pos1=0.01*sportzoneMax*user_hr_max; if (pos1>=FCmaxDisplay) pos1=FCmaxDisplay;if (pos1<=FCminDisplay) pos1=FCminDisplay;
	pos2=0.01*sportzoneMin*user_hr_max; if (pos2>=FCmaxDisplay) pos2=FCmaxDisplay;if (pos2<=FCminDisplay) pos2=FCminDisplay;
	nbpix=(pos1-pos2)*box.GRAPHHEIGHT/dynamic;

	if (nbpix!=0 && pos1>pos2)
	{
		sumpix+=nbpix;
		rectangle.setSize(QSize(box.GRAPHWIDTH,nbpix));
		painter.fillRect(rectangle,SPcolor);
		rectangle.translate(0,nbpix);
		if (nbpix>=2.0*fontsize) painter.drawText(fontsize,sumpix-nbpix/2,legend);
	}
}

void graph::drawBG()
{
	if (default_graph_configuration->backgroundType==0) drawPolarBG();
	else drawGraphPaperBG();
}

void graph::drawGraphPaperBG()
{
	float rangeY = (FCmaxDisplay-FCminDisplay)/box.GRAPHHEIGHT;
	QColor colorMajor( 247, 201, 204, 255 );
	QColor colorMinor( 247, 201, 204, 50 );
	
	int spaceMinor=2.0/rangeY;
	if (spaceMinor==0) spaceMinor=1;
	gPen.setWidth(1);
	gPen.setStyle(Qt::SolidLine);
	
	float step=box.GRAPHHEIGHT/25.0;
	int i0=0;
	for (unsigned i=0;i<box.GRAPHHEIGHT;i+=step)
	{
		if (i0%5==0) gPen.setColor(colorMajor);
		else gPen.setColor(colorMinor);
				scene->addLine(box.GRAPHOX,box.GRAPHHEIGHT-i+box.GRAPHOY,
									 box.GRAPHOX+box.GRAPHWIDTH,box.GRAPHHEIGHT-i+box.GRAPHOY,gPen);
		i0++;
	}
	
	i0=0;
	for (unsigned i=0;i<box.GRAPHWIDTH;i+=step)
	{
		if (i0%5==0) gPen.setColor(colorMajor);
		else gPen.setColor(colorMinor);
		scene->addLine(box.GRAPHOX+i,box.GRAPHOY,box.GRAPHOX+i,box.GRAPHOY+box.GRAPHHEIGHT,gPen);
		i0++;
	}
	
	/*
	for (int i=FCminDisplay;i<FCmaxDisplay;i+=2)
	{
		if (i%10==0) gPen.setColor(colorMajor);
		else gPen.setColor(colorMinor);

		scene->addLine(box.GRAPHOX,box.GRAPHHEIGHT-(i-FCminDisplay)/rangeY+box.GRAPHOY,
									 box.GRAPHOX+box.GRAPHWIDTH,box.GRAPHHEIGHT-(i-FCminDisplay)/rangeY+box.GRAPHOY,gPen);
	}

	for (int i=0;i<box.GRAPHWIDTH/spaceMinor;i+=1)
	{
		if (i%5==0) gPen.setColor(colorMajor);
		else gPen.setColor(colorMinor);
		scene->addLine(box.GRAPHOX+i*spaceMinor,box.GRAPHOY,box.GRAPHOX+i*spaceMinor,box.GRAPHOY+box.GRAPHHEIGHT,gPen);
	}
*/
}

void graph::drawPolarBG()
{
	const int dynamic = FCmaxDisplay-FCminDisplay;
	QPixmap sourceImage(box.GRAPHWIDTH,box.GRAPHHEIGHT);
	QPainter painter(&sourceImage);

	QPen textPen(Qt::white,1);
	painter.setPen(textPen);
	QFont myfont;
	int fontsize=12*box.ratio2normal;
	myfont.setPixelSize(fontsize);
	painter.setFont(myfont);
	
	if (dynamic!=0)
	{
		int sumpix=0;

		draw1sportzone(painter,sportzone[5],sportzone[4],default_graph_configuration->colors.c5,sumpix,dynamic,
									 QObject::tr("maximal intensity"),fontsize);
		draw1sportzone(painter,sportzone[4],sportzone[3],default_graph_configuration->colors.c4,sumpix,dynamic,
									 QObject::tr("heavy intensity"),fontsize);
		draw1sportzone(painter,sportzone[3],sportzone[2],default_graph_configuration->colors.c3,sumpix,dynamic,
									 QObject::tr("average intensity"),fontsize);
		draw1sportzone(painter,sportzone[2],sportzone[1],default_graph_configuration->colors.c2,sumpix,dynamic,
									 QObject::tr("light intensity"),fontsize);
		draw1sportzone(painter,sportzone[1],sportzone[0],default_graph_configuration->colors.c1,sumpix,dynamic,
									 QObject::tr("very light intensity"),fontsize);
		//other
		int nbpix=box.GRAPHHEIGHT-sumpix;
		if (nbpix!=0)
		{
			QRectF rectangle(0,sumpix,0,0);
			rectangle.setSize(QSize(box.GRAPHWIDTH,box.GRAPHHEIGHT-nbpix));
			painter.fillRect(rectangle,default_graph_configuration->colors.c0);
		}
	}
	else
	{
		QRectF rectangle(0,0,0,0);
		rectangle.setSize(QSize(box.GRAPHWIDTH,box.GRAPHHEIGHT));
		painter.fillRect(rectangle,default_graph_configuration->colors.c0);
		QString chaine0 = QObject::tr("wrong data");
		myfont.setPixelSize(60*box.ratio2normal);
		painter.setFont(myfont);
		painter.drawText(0,box.GRAPHHEIGHT/2,chaine0);
	}
	
	QGraphicsPixmapItem *pixm = scene->addPixmap(sourceImage);
	pixm->moveBy(box.GRAPHOX,box.GRAPHOY);
	pixm->setZValue(-1000000); //if not, it can be on top of others!
}


lapsGraph::lapsGraph(hrm_data &_data, graph_configuration *default_graph_configuration0)
{
	default_graph_configuration=default_graph_configuration0;
	data=_data;
	data.session->refCount++;
	data.pddContent->refCount++;
}

lapsGraph::~lapsGraph()
{
	releaseData();
}

void lapsGraph::releaseData()
{
	data.session->refCount--;
	data.pddContent->refCount--;
}

void lapsGraph::drawAxes()
{
  drawAxisBottom(QObject::tr("lap"), Qt::black, BASE10AXIS, 0.0, data.session->lap.size());
	drawAxisLeft(QObject::tr("Length"), Qt::red, BASE60AXIS, FCminDisplay, FCmaxDisplay);

	gPen.setColor(Qt::black);
	scene->addRect(box.GRAPHOX,box.GRAPHOY,box.GRAPHWIDTH,box.GRAPHHEIGHT);
}

void lapsGraph::initializeAxesScales()
{
	FCmaxDisplay=0; //minutes
	FCminDisplay=99999999; //minutes
	for (unsigned int i=0;i<data.session->lap.size();i++)
	{
		if (data.session->lap[i].laptime>FCmaxDisplay) FCmaxDisplay=data.session->lap[i].laptime;
		if (data.session->lap[i].laptime<FCminDisplay) FCminDisplay=data.session->lap[i].laptime;
	}
}

void lapsGraph::drawData()
{
	float minx=0;
	float maxx=data.session->lap.size(); //NumPointsDisplay;

	float rangeX = (maxx-minx)/box.GRAPHWIDTH;
	float rangeY = (FCmaxDisplay-FCminDisplay)/box.GRAPHHEIGHT;

	gPen.setColor(Qt::blue);
	gPen.setWidth(1);
	for (unsigned int i=0;i<data.session->lap.size()-1;i++)
	{
		float tmp1 = data.session->lap[i].laptime; //don't modify original data
		float tmp2 = data.session->lap[i+1].laptime; //don't modify original data

		QPointF un ( (float)i/rangeX+box.GRAPHOX,box.GRAPHHEIGHT-(tmp1-FCminDisplay)/rangeY+box.GRAPHOY);
		QPointF deux ( (float)(i+1)/rangeX+box.GRAPHOX,box.GRAPHHEIGHT-(tmp2-FCminDisplay)/rangeY+box.GRAPHOY);

		QLineF tmp(un,deux);
		scene->addLine(tmp,gPen);
	}
}

void lapsGraph::plot()
{
	initializeAxesScales();
	drawGraphPaperBG();
	drawData();
	drawAxes();
}

sessionGraph::sessionGraph(graph_configuration *default_graph_configuration0)
{
	default_graph_configuration=default_graph_configuration0;
	selOK=false;
	rectLap=NULL;
	textLap=NULL;
	SelectionItm=NULL;
	colors.push_back(Qt::red);
	colors.push_back(Qt::darkGreen);
	colors.push_back(Qt::blue);
	colors.push_back(Qt::cyan);
	colors.push_back(Qt::magenta);
	colors.push_back(Qt::darkYellow);
}
void sessionGraph::addData(hrm_data &hr)
{
	hr.session->refCount++;
	hr.pddContent->refCount++;
	data.push_back(hr);
}

void sessionGraph::releaseData()
{
	for (unsigned int i=0;i<data.size();i++)
	{
		data[i].session->refCount--;
		data[i].pddContent->refCount--;
	}
	data.clear();
}

hrm_data& sessionGraph::dataNumber(unsigned int index)
{
	return data[index];
}

unsigned int sessionGraph::dataSize()
{
	return data.size();
}

sessionGraph::~sessionGraph()
{
	if (data.size()==1) data[0].saveDATA();
	releaseData();
}


void sessionGraph::initializeAxesScales()
{
  NumPointsDisplay=0;
  recording_rateDisplay=1;
  FCmaxDisplay=0;
  FCminDisplay=1000;

	for (unsigned int i=0;i<data.size();i++)
  {
		if (data[i].session->number_of_samples*data[i].session->recording_interval>=NumPointsDisplay*recording_rateDisplay)
		{
			NumPointsDisplay=data[i].session->number_of_samples;
			recording_rateDisplay=data[i].session->recording_interval;
			sportzone=data[i].session->sportzone;
		}

		SPEEDmaxDisplay=default_graph_configuration->SPEEDmaxDisplay;
		SPEEDminDisplay=default_graph_configuration->SPEEDminDisplay;
		
		if (default_graph_configuration->boundType==0)
		{
			//use user fcmin and fcmax
			if (data[i].session->user_hr_max>=FCmaxDisplay)  FCmaxDisplay=data[i].session->user_hr_max;
			if (data[i].session->user_hr_rest<=FCminDisplay) FCminDisplay=data[i].session->user_hr_rest;
		}
		else if (default_graph_configuration->boundType==1)
		{
				//use curves fcmin/fcmax
				if (data[i].statsAll.HRmax>=FCmaxDisplay)  FCmaxDisplay=data[i].statsAll.HRmax;
				if (data[i].statsAll.HRmin<=FCminDisplay) FCminDisplay=data[i].statsAll.HRmin;
		}
		else if (default_graph_configuration->boundType==2)
		{
				//use curves fcmin/fcmax
				FCmaxDisplay=default_graph_configuration->FCmaxDisplay;
				FCminDisplay=default_graph_configuration->FCminDisplay;
		}
	}
	user_hr_max=data[0].session->user_hr_max;
	user_hr_rest=data[0].session->user_hr_rest;
	sportzone=data[0].session->sportzone;
}



void sessionGraph::drawHistograms()
{
	hrm_data* currentData=&data[0];
	QPen pinceau(Qt::black,1);
	QBrush brosse0;

	brosse0.setStyle(Qt::SolidPattern);
	brosse0.setColor(default_graph_configuration->colors.c0);
	float stepPC=100.0/currentData->nbbins;
	for (unsigned int i=0;i<currentData->nbbins;i++)
	{
		if (i*stepPC>=sportzone[4]) brosse0.setColor(default_graph_configuration->colors.c5);
		else if (i*stepPC>=sportzone[3]) brosse0.setColor(default_graph_configuration->colors.c4);
		else if (i*stepPC>=sportzone[2]) brosse0.setColor(default_graph_configuration->colors.c3);
		else if (i*stepPC>=sportzone[1]) brosse0.setColor(default_graph_configuration->colors.c2);
		else if (i*stepPC>=sportzone[0]) brosse0.setColor(default_graph_configuration->colors.c1);
		else brosse0.setColor(default_graph_configuration->colors.c0);

		int w=10*box.ratio2normal;
		
	/*QGraphicsRectItem*	tmp =*/ scene->addRect(QRectF(box.HISTOGRAM_OX+i*w,box.HISTOGRAM_OY-currentData->histogram[i]*10*w,w, currentData->histogram[i]*10*w),pinceau,brosse0);
	}
}

void sessionGraph::plot()
{
	//remove widgets etc...
	QList<QGraphicsItem *> 	itms=scene->items(box.GRAPHOX,box.GRAPHOY,box.THUMBWIDTH,box.THUMBHEIGHT);
	for (/*unsigned*/ int i=0;i<itms.size();i++) scene->removeItem(itms[i]);
	
	//computeBBox(g,0,0,nbthumbh,nbthumbv,width(),height());
	initializeAxesScales();
	
	//float ratio2normal=box.ratio2normal;
	

  if (NumPointsDisplay>0)
  {
		rectLap=NULL;
		textLap=NULL;
		SelectionItm=NULL;
		listeSelection.clear();
		

		//fill with white
		gBrush.setStyle(Qt::SolidPattern);
		gPen.setColor(Qt::white);

		if (data[0].has_changed==0) gBrush.setColor(Qt::white);
		else gBrush.setColor(default_graph_configuration->colors.transpRed);
			
		scene->addRect(QRectF(box.THUMBOX,box.THUMBOY,box.THUMBWIDTH,box.THUMBHEIGHT),gPen,gBrush)->setZValue(-1000001);//if not, it can be on top of others!

		//we already know sportzones here:
		drawBG();
		drawHR();
		drawSPEED();
		drawLaps();

		if (data.size()==1)
		{
			drawSelections();  
			drawHistograms();
			drawLegends();
		}
		else
		{
			drawLegendsComparison();
		}
		drawAxes();
	}
}

void sessionGraph::plotPreview(unsigned int width, unsigned int height)
{
	data[0].computeStatistics();
	initializeAxesScales();
	float ratio2normal=box.ratio2normal;
  if (NumPointsDisplay>0)
  {
		//remove widgets etc...
		QList<QGraphicsItem *> 	itms=scene->items(box.THUMBOX,box.THUMBOY,box.THUMBWIDTH,box.THUMBHEIGHT);
		for (/*unsigned*/ int i=0;i<itms.size();i++) scene->removeItem(itms[i]);

		scene->setSceneRect(0,0,width,height);
		//fill with white
		gBrush.setStyle(Qt::SolidPattern);
		gBrush.setColor(Qt::white);
		gPen.setColor(Qt::black);
		scene->addRect(QRectF(-10*ratio2normal,-10*ratio2normal,width+10*ratio2normal,height+10*ratio2normal),gPen,gBrush)->setZValue(-1000001);// background

		//we already know sportzones here:
		drawBG();
		drawHR();
		drawSPEED();
		drawLaps();
		//drawHistograms(previewscene);
		//drawLegends(previewscene);
		drawAxes();
	}
}

void sessionGraph::drawCursor(int x, int y)
{
	//choose position
	int x0,y0;
	x0=x+250>2*box.GRAPHOX+box.GRAPHWIDTH?x-300:x;
	y0=y-100<0?y+150:y;

	//setCursor(Qt::ArrowCursor);
	hrm_data* currentData=&data[0];
	QString du;
	if (rectLap!=NULL) {scene->removeItem((QGraphicsItem *)rectLap);rectLap=NULL;}
	if (textLap!=NULL) {scene->removeItem((QGraphicsItem *)textLap);textLap=NULL;}
	int currentTime=((x-box.GRAPHOX)/(float)box.GRAPHWIDTH)*NumPointsDisplay*recording_rateDisplay;
	int dynamic = FCmaxDisplay-FCminDisplay;
	int currentHR = ((box.GRAPHHEIGHT-(y-box.GRAPHOY))/(float)box.GRAPHHEIGHT)*dynamic+FCminDisplay;

	if (currentTime>=0 && currentTime<=(int)currentData->statsAll.duration && currentHR>=FCminDisplay && currentHR<=FCmaxDisplay)
	{
		//where are we in the laps?
		int lap=0;
		for (unsigned int i=0;i<data[0].session->lap.size();i++) //don't use the last one
		{
			if (currentTime>=data[0].session->lap[i].lap_end_time-data[0].session->lap[i].laptime) lap=i;
		}
	
		char duration[12];
		char start[12];
		char current[12];
		
		double begin=data[0].session->lap[lap].lap_end_time-data[0].session->lap[lap].laptime;
		double length=data[0].session->lap[lap].laptime;
		
		timetostr(start, begin);
		timetostr(duration, length);
		timetostr(current, currentTime);
	
		QString du2=QObject::tr("Lap start: ")+QString(start)+QChar('\n')
		+QObject::tr("Lap length: ")+QString(duration)+QChar('\n');
		du2+=QObject::tr("Cursor: ")+QString(current)+" "+QString::number(currentHR)+QObject::tr(" BPM");

		float pixelDistance1=box.GRAPHWIDTH*fabs(currentTime-begin)/data[0].session->duration;
		float pixelDistance2=box.GRAPHWIDTH*fabs(currentTime-(begin+length))/data[0].session->duration;
		if (pixelDistance1<=3 || pixelDistance2<=3)
		{
			//setCursor(Qt::SizeHorCursor);
		}
		else
		{
			//setCursor(Qt::ArrowCursor);
			gBrush.setStyle(Qt::SolidPattern);
			gBrush.setColor(Qt::white);
			gPen.setColor(Qt::black);

			rectLap=scene->addRect(QRectF(x0,y0-100,250,60),gPen,gBrush);
			rectLap->setZValue(1000000);
			
			textLap = scene->addText(du2);
			textLap -> setPos(x0,y0-100);
			textLap -> setDefaultTextColor(Qt::black);
			textLap->setZValue(1000001);
		}
	}
}


void sessionGraph::drawHR()
{
	for (unsigned int i0=0;i0<data.size();i0++)
	{
		hrm_data* currentData=&data[i0];
		if (currentData->session->number_of_samples!=0)
		{
			float minx=0;
			float maxx=NumPointsDisplay;

			float rangeX = (maxx-minx)/box.GRAPHWIDTH;
			float rangeY = (FCmaxDisplay-FCminDisplay)/box.GRAPHHEIGHT;

		//draw hr curve and compute global HR stats
			QPolygonF polygon;
			//polygon.clear();
			polygon<<QPointF(box.GRAPHOX,box.GRAPHHEIGHT+box.GRAPHOY);

			for (unsigned int i=0;i<currentData->session->number_of_samples;i++)
			{
				float tmp = currentData->session->sample[i].hr; //don't modify original data

				//data correction for plot: don't go away from the screen
				if (tmp > FCmaxDisplay) tmp=FCmaxDisplay;
				if (tmp < FCminDisplay) tmp=FCminDisplay;
				polygon<<QPointF( (float)i/rangeX+box.GRAPHOX,box.GRAPHHEIGHT-(tmp-FCminDisplay)/rangeY+box.GRAPHOY);
			}
			
			polygon<<QPointF((float)(currentData->session->number_of_samples-1)/rangeX+box.GRAPHOX,box.GRAPHHEIGHT+box.GRAPHOY);
			polygon<<QPointF(box.GRAPHOX,box.GRAPHHEIGHT+box.GRAPHOY);

			gPen.setColor(colors[i0%colors.size()]);
			gPen.setWidth(1);
			
			if (data.size()==1)
			{
				gBrush.setStyle(Qt::SolidPattern);
				gBrush.setColor(default_graph_configuration->colors.transpWhite);
			}
			else
			{
				gBrush.setStyle(Qt::NoBrush);
			}
			scene->addPolygon(polygon,gPen,gBrush);
		}
	}
}


void sessionGraph::drawSPEED()
{
	float rangeSPEED=(SPEEDmaxDisplay-SPEEDminDisplay)/box.GRAPHHEIGHT;

	float minx=0;
	float maxx=NumPointsDisplay;
	float rangeX = (maxx-minx)/box.GRAPHWIDTH;

	for (unsigned int i0=0;i0<data.size();i0++)
	{
		hrm_data* currentData=&data[i0];
		if (currentData->session->has_pace_data)
		{
			gPen.setWidth(1);
			gPen.setColor(Qt::blue);
			for (unsigned int i=0;i<currentData->session->number_of_samples-1;i++)
			{
				//speeds are in tenths of km/h
				if (currentData->session->sample[i].speed > 10*SPEEDmaxDisplay) currentData->session->sample[i].speed=10*SPEEDmaxDisplay;
				if (currentData->session->sample[i].speed < 10*SPEEDminDisplay) currentData->session->sample[i].speed=10*SPEEDminDisplay;

				QPointF un ( (float)i/rangeX+box.GRAPHOX,box.GRAPHOY+box.GRAPHHEIGHT-(0.1*currentData->session->sample[i].speed-SPEEDminDisplay)/rangeSPEED);
				QPointF deux( (float)(i+1)/rangeX+box.GRAPHOX,box.GRAPHOY+box.GRAPHHEIGHT-(0.1*currentData->session->sample[i+1].speed-SPEEDminDisplay)/rangeSPEED);
				QLineF tmp(un,deux);
				scene->addLine(tmp,gPen);
			//	polygonSPEED<<QPointF( (float)i/rangeX,GRAPHHEIGHT-(currentData->session->sample[i]->speed-SPEEDmin)/rangeSPEED);
			}
		}
	}
}

void sessionGraph::drawLaps()
{
	float rangeY = (FCmaxDisplay-FCminDisplay)/box.GRAPHHEIGHT;
	gPen.setColor(Qt::red);
	for (unsigned int i0=0;i0<data.size();i0++)
	{
		hrm_data* currentData=&data[i0];
		for (unsigned int i=0;i<currentData->session->lap.size()-1;i++) //don't use the last one
		{
			float HRval= currentData->session->lap[i].hr_end;
			if (HRval >FCmaxDisplay) HRval = FCmaxDisplay;

			int posx=box.GRAPHOX+box.GRAPHWIDTH * (float)(currentData->session->lap[i].lap_end_time)/(NumPointsDisplay*recording_rateDisplay);
			int posy=box.GRAPHOY+box.GRAPHHEIGHT-(HRval-FCminDisplay)/rangeY;
			scene->addLine(posx,box.GRAPHHEIGHT+box.GRAPHOY,posx,posy,gPen);
			
			QString legend;
			if (currentData->session->lap[i].laptype==33554432)
			{
				legend=QString("P")+QString::number(currentData->session->lap[i].lap_no);
			}
				else
			{
				legend=QString::number(currentData->session->lap[i].lap_no);
			}
			scene->addText( legend,box.myfont)-> setPos(posx ,posy-30*box.ratio2normal);
		}
	}
}


void sessionGraph::drawAxes()
{
	hrm_data* currentData=&data[0];
	int nbp = NumPointsDisplay;
	float range = nbp*currentData->session->recording_interval;

  drawAxisBottom(QObject::tr("time"), Qt::black, BASE60AXIS, 0.0, range);
	drawAxisLeft(QObject::tr("HR [bpm]"), Qt::red, BASE10AXIS, FCminDisplay, FCmaxDisplay);
	if (currentData->session->has_pace_data) drawAxisRight(QObject::tr("speed(km/h)"), Qt::blue,BASE10AXIS,SPEEDminDisplay, SPEEDmaxDisplay);

	gPen.setColor(Qt::black);
	scene->addRect(box.GRAPHOX,box.GRAPHOY,box.GRAPHWIDTH,box.GRAPHHEIGHT);
}

void sessionGraph::drawLegendsComparison()
{
	char time2[12];
	gBrush.setStyle(Qt::SolidPattern);
	for (unsigned int i=0;i<data.size();i++)
	{
		int line=i%3;
		int column=i/3;
		gPen.setColor(colors[i%colors.size()]);
		hrm_data* currentData=&data[i];
		//scene->addText( QObject::tr("Date:"),box.myfont)-> setPos(box.LEGEND1_OX ,box.LEGEND1_OY);
		scene->addLine(box.LEGEND1_OX+column*200*box.ratio2normal,
									 box.LEGEND1_OY+line*20*box.ratio2normal+box.myfontsize,
									 box.LEGEND1_OX+column*200*box.ratio2normal+50*box.ratio2normal,
									 box.LEGEND1_OY+line*20*box.ratio2normal+box.myfontsize,gPen);
									 
		hmstostr(time2,currentData->session->day,currentData->session->month,currentData->session->year-2000,'/');
		QString du=QString(time2);
		scene->addText( du,box.myfont)-> setPos(70*box.ratio2normal+column*200*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY+line*20*box.ratio2normal);
	}
}


void sessionGraph::drawLegends()
{
	hrm_data* currentData=&data[0];
	//legend total:
	gBrush.setStyle(Qt::SolidPattern);
	gBrush.setColor(default_graph_configuration->colors.greyBG);

	gPen.setColor(Qt::black);
	gPen.setWidth(1);
	QGraphicsRectItem *rect=scene->addRect(QRectF(box.LEGEND1_OX,box.LEGEND1_OY,250*box.ratio2normal,60*box.ratio2normal),gPen,gBrush);
	rect->setZValue(-1000000); //if not, it can be on top of others!

	scene->addLine(145*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY,145*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY+60*box.ratio2normal,gPen);

	scene->addText( QObject::tr("Date:"),box.myfont)-> setPos(box.LEGEND1_OX ,box.LEGEND1_OY);
	scene->addText( QObject::tr("Start Time:"),box.myfont)-> setPos(box.LEGEND1_OX ,box.LEGEND1_OY+20*box.ratio2normal);
	scene->addText( QObject::tr("Duration:"),box.myfont)-> setPos(box.LEGEND1_OX ,box.LEGEND1_OY+40*box.ratio2normal);

	scene->addText( QObject::tr("max HR:"),box.myfont)-> setPos(box.LEGEND1_OX+150*box.ratio2normal ,box.LEGEND1_OY);
	scene->addText( QObject::tr("min HR:"),box.myfont)-> setPos(box.LEGEND1_OX+150*box.ratio2normal ,box.LEGEND1_OY+20*box.ratio2normal);
	scene->addText( QObject::tr("av. HR:"),box.myfont)-> setPos(box.LEGEND1_OX+150*box.ratio2normal ,box.LEGEND1_OY+40*box.ratio2normal);

	scene->addText(QString::number(currentData->statsAll.HRmax),box.myfont)-> setPos(220*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY);
	scene->addText(QString::number(currentData->statsAll.HRmin),box.myfont)-> setPos(220*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY+20*box.ratio2normal);
	scene->addText(QString::number((int)currentData->statsAll.HRAverage),box.myfont)-> setPos(220*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY+40*box.ratio2normal);

	char duration[12],time2[12];

	timetostr(duration, currentData->statsAll.duration);
	QString du=QString(duration);

	hmstostr(time2,currentData->session->start_hour,currentData->session->start_minute,currentData->session->start_second,':');
	QString st=QString(time2);

	hmstostr(time2,currentData->session->day,currentData->session->month,currentData->session->year-2000,'/');
	QString da=QString(time2);

	scene->addText( da,box.myfont)-> setPos(70*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY);
	scene->addText( st,box.myfont)-> setPos(70*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY+20*box.ratio2normal);
	scene->addText( du,box.myfont)-> setPos(70*box.ratio2normal+box.LEGEND1_OX,box.LEGEND1_OY+40*box.ratio2normal);
	
	//show comment:
	QString comment=QObject::tr("Note: ")+QString(currentData->session->comment);
	scene->addText( comment,box.myfont)-> setPos(box.LEGEND1_OX ,box.LEGEND1_OY+60*box.ratio2normal);

	//legend selections:
	if (listeSelection.size()!=0)
	{
		QGraphicsTextItem* tmp = scene->addText(QObject::tr("Sel. Max HR: ")+QString::number(currentData->statsSelection.HRmax),box.myfont);
		tmp-> setDefaultTextColor(Qt::blue);
		tmp->setPos(box.LEGEND2_OX ,box.LEGEND2_OY);
		//statdisp.push_back(tmp);
	
		tmp = scene->addText(QObject::tr("Sel. Min HR: ")+QString::number(currentData->statsSelection.HRmin),box.myfont);
		tmp-> setDefaultTextColor(Qt::blue);
		tmp->setPos(box.LEGEND2_OX ,box.LEGEND2_OY+20*box.ratio2normal);
		//statdisp.push_back(tmp);

		tmp = scene->addText(QObject::tr("Sel. Av HR:")+QString::number((int)(currentData->statsSelection.HRAverage)),box.myfont);
		tmp-> setDefaultTextColor(Qt::blue);
		tmp->setPos(box.LEGEND2_OX ,box.LEGEND2_OY+40*box.ratio2normal);
		//statdisp.push_back(tmp);

	char duration[12];
	timetostr(duration, currentData->statsSelection.duration);
	QString du=QString(duration);
	
		tmp = scene->addText(QObject::tr("Sel. duration: ")+du,box.myfont);
		tmp-> setDefaultTextColor(Qt::blue);
		tmp->setPos(box.LEGEND2_OX+110*box.ratio2normal ,box.LEGEND2_OY);
		//statdisp.push_back(tmp);

		tmp = scene->addText(QObject::tr("Sel. calories (Kcal): ")+QString::number((int)currentData->statsSelection.energy),box.myfont);
		tmp-> setDefaultTextColor(Qt::blue);
		tmp->setPos(box.LEGEND2_OX+110*box.ratio2normal,box.LEGEND2_OY+20*box.ratio2normal);
		//statdisp.push_back(tmp);
	}
}

void sessionGraph::drawSelections()
{
//selections
	float posi = box.GRAPHOY+box.GRAPHHEIGHT-10*box.ratio2normal;
	gPen.setColor(Qt::blue);
	gPen.setWidth(1);
	gBrush.setStyle(Qt::SolidPattern);
	gBrush.setColor(Qt::blue);

	hrm_data* currentData=&data[0];
	for (unsigned int i=0;i<currentData->session->selections.size();i++)
	{
		float beginning=(float)currentData->session->selections[i].low/currentData->session->number_of_samples;
		float ending=(float)currentData->session->selections[i].high/currentData->session->number_of_samples;
		if ( !(beginning<0 || beginning > 1 || ending <0 || ending >1))
		{
			QRectF tmp(beginning*box.GRAPHWIDTH+box.GRAPHOX,posi,(ending-beginning)*box.GRAPHWIDTH,10*box.ratio2normal);
			QGraphicsRectItem* itm = scene->addRect(tmp,gPen,gBrush);
			itm->setZValue(1); 
			listeSelection.push_back(itm);
		}
	}
}


int sessionGraph::mousePressEvent(Qt::MouseButton button, QPointF &tmp1)
{
	if (box.GRAPHHEIGHT!=0 && box.GRAPHWIDTH!=0 && data.size()==1)
	{
		//QPointF tmp1 = mapToScene(event->pos());
		if (tmp1.y()>(box.GRAPHHEIGHT+box.GRAPHOY-20*box.ratio2normal) && tmp1.y()<=(box.GRAPHHEIGHT+box.GRAPHOY+10*box.ratio2normal))
		{
			// right mouse button: delete selection
			if (button== Qt::RightButton)
			{
				for (int i=listeSelection.size()-1;i>=0;i--)
				{
					if (listeSelection[i]->rect().contains(tmp1))
					{
						scene->removeItem(listeSelection[i]);
						listeSelection.erase(listeSelection.begin()+i);
						data[0].session->selections.erase(data[0].session->selections.begin()+i);
						data[0].has_changed=1;
					}
				}
				data[0].computeStatistics();
				plot();
				//plotSession();
			}
			//left button: start selecting
			else if (button== Qt::LeftButton)
			{
				initial = tmp1;
				selOK=true;
			}
			return 0;
		}
		else
		{
			selOK=false;
		}
	}
	return 1;
}

void sessionGraph::leave()
{
	if (SelectionItm!=NULL) {scene->removeItem(SelectionItm);SelectionItm=NULL;}
	if (rectLap!=NULL) {scene->removeItem((QGraphicsItem *)rectLap);rectLap=NULL;}
	if (textLap!=NULL) {scene->removeItem((QGraphicsItem *)textLap);textLap=NULL;}
}

int sessionGraph::mouseMoveEvent (QPointF &tmp1)
{
	if (box.GRAPHHEIGHT!=0 && box.GRAPHWIDTH!=0 && data.size()==1)
	{
		//QPointF tmp1 = mapToScene(event->pos());
		drawCursor(tmp1.x(),tmp1.y());
		
		if (selOK)
		{
			if (SelectionItm!=NULL) {scene->removeItem(SelectionItm);SelectionItm=NULL;}
			
			QPen pinceau(Qt::blue,1);
			QBrush brosse0;
			brosse0.setStyle(Qt::SolidPattern);
			brosse0.setColor(Qt::blue);

			final = tmp1;
			//toto1 = mapToScene(initial);
			//toto2 = mapToScene(final);

			if (initial.x()<box.GRAPHOX) initial.setX(box.GRAPHOX);
			if (initial.x()>box.GRAPHOX+box.GRAPHWIDTH) initial.setX(box.GRAPHOX+box.GRAPHWIDTH);

			if (final.x()<box.GRAPHOX) final.setX(box.GRAPHOX);
			if (final.x()>box.GRAPHOX+box.GRAPHWIDTH) final.setX(box.GRAPHOX+box.GRAPHWIDTH);

			float posi = box.GRAPHOY+box.GRAPHHEIGHT;
			
			QRectF tmp(initial.x(),posi-10*box.ratio2normal,final.x()-initial.x(),10*box.ratio2normal);
			float wd = tmp.width();
			if (wd<0)
			{
				tmp.setX(tmp.x()+tmp.width());tmp.setWidth(-wd);
			}
			SelectionItm = scene->addRect(tmp,pinceau,brosse0);
			SelectionItm->setZValue(1);
		}
	}
	return 0;
}

int sessionGraph::mouseReleaseEvent(Qt::MouseButton button, QPointF& /*tmp1*/)
{
	if (box.GRAPHHEIGHT!=0 && box.GRAPHWIDTH!=0 && data.size()==1)
	{
		if (button==  Qt::LeftButton && selOK)
		{
			if (data[0].session->selections.size()<20)
			{
				SelectionItm=NULL;
				if (fabs(initial.x()-final.x())>=3) //don't keep buggy (wrong clics?) selections
				{
					float one = ((initial.x()-box.GRAPHOX)/box.GRAPHWIDTH)*data[0].session->number_of_samples;
					float two = ((final.x()-box.GRAPHOX)/box.GRAPHWIDTH)*data[0].session->number_of_samples;
					float tmpsw;
					if (one>two) {tmpsw=two;two=one;one=tmpsw;}
					rs400_selection newselection;
					newselection.low=one;
					newselection.high=two;
					data[0].session->selections.push_back(newselection);
					data[0].has_changed=1;
					data[0].computeStatistics();
				}
				selOK=false;
				//plotSession();
				plot();
			}
		}
	}
	return 0;
}




void basicExoGraph::setWorkingExercise(polarLINUXio_basic_exercise* _exo)
{
	exo=_exo;
}


void basicExoGraph::drawAxes()
{
	drawAxisLeft(QObject::tr("HR [bpm]"), Qt::red, BASE10AXIS, FCminDisplay, FCmaxDisplay);
	if (hasSpeed==1) drawAxisRight(QObject::tr("speed(km/h)"), Qt::blue, BASE10AXIS,SPEEDminDisplay, SPEEDmaxDisplay);
	if (hasTime!=0) drawAxisBottom(QObject::tr("time"), Qt::black, BASE60AXIS, 0.0, totalTime);
}

void basicExoGraph::plot()
{
	initializeAxesScales(); //calls graph:: default configuration
	gBrush.setStyle(Qt::SolidPattern);
	hasSpeed=0;

	drawBG();

	float estimatedSpeed=14.0;
	totalTime=0;
	float sizeFixed=0;

	std::vector<int> zonelength;
	std::vector<int> fcmin;
	std::vector<int> fcmax;
	
	if (exo->num_zones>=1) zonelength.push_back(exo->zone1length);
	if (exo->num_zones>=2) zonelength.push_back(exo->zone2length);
	if (exo->num_zones>=3) zonelength.push_back(exo->zone3length);
	
	//compute total time
	if (exo->guideType==0) //manual
	{
		hasTime=0;
		sizeFixed=10;
		for (int i=0;i<exo->num_zones;i++) {zonelength[i]=sizeFixed;totalTime+=zonelength[i];}
	}
	else if (exo->guideType==1)
	{
		hasTime=1;
		//totalTime*=0.60; //gives seconds
		for (int i=0;i<exo->num_zones;i++) {zonelength[i]*=(60.0/100.0);totalTime+=zonelength[i];}
	}
	else if (exo->guideType==2) //distance
	{
		hasTime=1;
		for (int i=0;i<exo->num_zones;i++) {zonelength[i]*=36.0/estimatedSpeed;totalTime+=zonelength[i];}
	}

	//plot each
	if (totalTime!=0)
	{
		float propX=(box.GRAPHWIDTH-(exo->num_zones+2)*5)/totalTime;
		float propy=box.GRAPHHEIGHT/(FCmaxDisplay-FCminDisplay);
		float propy2=box.GRAPHHEIGHT/(SPEEDmaxDisplay-SPEEDminDisplay);
		int shiftx=box.GRAPHOX;
		int duration=0;
		int posy;
		int height;
		
		for (unsigned int i=0;i<zonelength.size();i++)
		{
			unsigned char *FCmin=NULL, *FCmax=NULL;
			if (i==0) {FCmin=exo->FC1min;FCmax=exo->FC1max;}
			if (i==1) {FCmin=exo->FC2min;FCmax=exo->FC2max;}
			if (i==2) {FCmin=exo->FC3min;FCmax=exo->FC3max;}
			
			duration=zonelength[i];
			if (exo->zones_type==0x04) //free
			{
				gBrush.setColor(default_graph_configuration->colors.transpWhite);
				posy=box.GRAPHOY;
				height=box.GRAPHHEIGHT;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			else if (exo->zones_type==0x14) //HR abs
			{
				float low=FCmin[0];
				float up=FCmax[0];
				checkBounds(low,FCminDisplay,FCmaxDisplay);
				checkBounds(up,FCminDisplay,FCmaxDisplay);
				
				gBrush.setColor(default_graph_configuration->colors.transpRed);
				posy=box.GRAPHOY+box.GRAPHHEIGHT-(low-FCminDisplay)*propy;
				height=-(up-low)*propy;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			else if (exo->zones_type==0x15) //HR %%
			{
				float low=FCmin[0]*FCmaxDisplay/100.;
				float up=FCmax[0]*FCmaxDisplay/100.;
				checkBounds(low,FCminDisplay,FCmaxDisplay);
				checkBounds(up,FCminDisplay,FCmaxDisplay);
				
				gBrush.setColor(default_graph_configuration->colors.transpRed);
				posy=box.GRAPHOY+box.GRAPHHEIGHT-(low-FCminDisplay)*propy;
				height=-(up-low)*propy;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			else if (exo->zones_type==0x1C) //ownzone
			{
				gBrush.setColor(default_graph_configuration->colors.transpWhite);
				posy=box.GRAPHOY;
				height=box.GRAPHHEIGHT;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			else if (exo->zones_type==0x18) //sportzone
			{
				int sz=(int)FCmin[0];
				if (sz>=0 && sz<=4)
				{
					float minfc,maxfc;
					minfc=sportzone[4-sz]*FCmaxDisplay/100.;
					maxfc=sportzone[4-sz+1]*FCmaxDisplay/100.;
					checkBounds(minfc,FCminDisplay,FCmaxDisplay);
					checkBounds(maxfc,FCminDisplay,FCmaxDisplay);

					gBrush.setColor(default_graph_configuration->colors.transpRed);
					posy=box.GRAPHOY+box.GRAPHHEIGHT-(minfc-FCminDisplay)*propy;
					height=-(maxfc-minfc)*propy;
					scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
				}
			}
			else if (exo->zones_type==0x24) //speed
			{
				hasSpeed=1;
				float speedmin=FCmin[1];
				float speedmax=FCmax[1];
				checkBounds(speedmin,SPEEDminDisplay,SPEEDmaxDisplay);
				checkBounds(speedmax,SPEEDminDisplay,SPEEDmaxDisplay);
				
				gBrush.setColor(default_graph_configuration->colors.transpBlue);
				posy=box.GRAPHOY+box.GRAPHHEIGHT-(speedmin-SPEEDminDisplay)*propy2;
				height=-(speedmax-speedmin)*propy2;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			else if (exo->zones_type==0x34) //pace
			{
				float valmin = msb_lsb_to_decimal(FCmin[1],FCmin[0]);
				float valmax = msb_lsb_to_decimal(FCmax[1],FCmax[0]);
				valmin=36000.0/valmin;
				valmax=36000.0/valmax;

				hasSpeed=1;
				checkBounds(valmin,SPEEDminDisplay,SPEEDmaxDisplay);
				checkBounds(valmax,SPEEDminDisplay,SPEEDmaxDisplay);
				
				gBrush.setColor(default_graph_configuration->colors.transpBlue);
				posy=box.GRAPHOY+box.GRAPHHEIGHT-(valmin-SPEEDminDisplay)*propy2;
				height=-(valmax-valmin)*propy2;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);	
			}
			shiftx+=propX*duration+5;
		}
	}
	drawAxes();
}

	
void advExoGraph::setWorkingExercise(polarLINUXio_advancedExo* _exo)
{
	exo=_exo;
}

void advExoGraph::plot()
{
	initializeAxesScales(); //calls graph:: default configuration
	
	//unsigned int *sportzone=gs.sportZvalues;
	std::list<int> block;
	for (int i=exo->numPhases-1;i>=0;i--) block.push_back(i);


	
	for (int i=exo->numPhases-1;i>=0;i--)
	{
	//for (it=block.begin();it!=block.end();it++) std::cout<<"it="<<*it<<" ";
	//std::cout<<std::endl;
		for (std::list<int>::iterator it=block.begin();it!=block.end();it++)
		{
			if (*it==i)
			{
				for (int rep=1;rep<exo->p[i].repeatNUM;rep++)
				{
				//	for (int j=i;j>=exo->p[i].repeatWhat;j--) block.insert(it,j);
					for (int j=i; j>=exo->p[i].repeatWhat-1;j--) block.insert(it,j);
				}
			//remove the orignal one which was replaced
			//block.erase(it);
			//it--;
			}
		}
	}
//	std::cout<<"result:"<<std::endl;
//	for (it=block.begin();it!=block.end();it++) std::cout<<"it="<<*it<<" ";
//	std::cout<<std::endl;

	drawBG();

	gBrush.setStyle(Qt::SolidPattern);
	gPen.setColor(Qt::black);
	
	//compute totalTime;
	totalTime=0;
	int posy;
	int height;
	int nbother=0; //manual, tohr
	float estimatedSpeed=14.0;
	float sizeFixed=0;
	hasSpeed=0;
	hasTime=0;
	for (std::list<int>::iterator it=block.begin();it!=block.end();it++)
	{
		int durationtype=exo->p[*it].durationtype;
		if (durationtype>=9) durationtype-=8;
		if (durationtype==2) //time
		totalTime+=hexa_to_same_decimal(exo->p[*it].duration1)*60+hexa_to_same_decimal(exo->p[*it].duration2);
		
		else if (durationtype==3) //distance
		totalTime+=3600*msb_lsb_to_decimal(exo->p[*it].duration1,exo->p[*it].duration2)/(100*estimatedSpeed);
		
		if (durationtype==1 || durationtype==4 || durationtype==5)
		{//manual, fc inc, fc dec
			nbother+=1;
		}
	}
	if (totalTime!=0)
	{
		hasTime=1;
		sizeFixed=0.1*totalTime;
	}
	else
	{
		hasTime=0;
		sizeFixed=10;
	}

	totalTime+=nbother*sizeFixed; //each other is 10% of the total
	
	if (totalTime!=0 )
	{
		float propX=(box.GRAPHWIDTH-(block.size()+2)*5)/totalTime;
		float propy=box.GRAPHHEIGHT/(FCmaxDisplay-FCminDisplay);
		float propy2=box.GRAPHHEIGHT/(SPEEDmaxDisplay-SPEEDminDisplay);
		int shiftx=box.GRAPHOX;
		int duration=0;
		for (std::list<int>::reverse_iterator rit=block.rbegin();rit!=block.rend();rit++)
		{
			int durationtype=exo->p[*rit].durationtype;
			if (durationtype>=9)
			{
				durationtype-=8;
				gPen.setColor(Qt::red);
			}
			else gPen.setColor(Qt::black);
			//horizontal scale:
			if (durationtype==2) //time
			{
			duration=hexa_to_same_decimal(exo->p[*rit].duration1)*60+hexa_to_same_decimal(exo->p[*rit].duration2);
			}
			else if (durationtype==3) //distance
			{
				duration=3600*msb_lsb_to_decimal(exo->p[*rit].duration1,exo->p[*rit].duration2)/(100*estimatedSpeed);
			}
			else //manual, increase, decrease
			{
				duration=sizeFixed;
				
			}
			
			if (durationtype==4) //increase
			{
				float HRtarget=(float)exo->p[*rit].duration2;
				checkBounds(HRtarget,FCminDisplay,FCmaxDisplay);
				
				height=-(HRtarget-FCminDisplay)*propy;
				gBrush.setColor(default_graph_configuration->colors.transpRed);
				QPolygonF polygon;
				polygon<<QPointF(shiftx,box.GRAPHOY+box.GRAPHHEIGHT);
				polygon<<QPointF(shiftx+propX*duration,box.GRAPHOY+box.GRAPHHEIGHT);
				polygon<<QPointF(shiftx+propX*duration,box.GRAPHOY+box.GRAPHHEIGHT+height);
				polygon<<QPointF(shiftx,box.GRAPHOY+box.GRAPHHEIGHT);
				scene->addPolygon(polygon,gPen,gBrush);
			}
			else if (durationtype==5) //decrease
			{
				float HRtarget=(float)exo->p[*rit].duration2;
				checkBounds(HRtarget,FCminDisplay,FCmaxDisplay);
				
				height=-(HRtarget-FCminDisplay)*propy;
				gBrush.setColor(default_graph_configuration->colors.transpRed);
				QPolygonF polygon;
				polygon<<QPointF(shiftx,box.GRAPHOY+box.GRAPHHEIGHT+height);
				polygon<<QPointF(shiftx+propX*duration,box.GRAPHOY+box.GRAPHHEIGHT+height);
				polygon<<QPointF(shiftx,box.GRAPHOY);
				polygon<<QPointF(shiftx,box.GRAPHOY+box.GRAPHHEIGHT+height);
				scene->addPolygon(polygon,gPen,gBrush);
			}
			//vertical scale
			else if (exo->p[*rit].guidetype==0x14) //HR abs
			{
				float low=exo->p[*rit].FClow[0];
				float up=exo->p[*rit].FCHigh[0];
				checkBounds(low,FCminDisplay,FCmaxDisplay);
				checkBounds(up,FCminDisplay,FCmaxDisplay);
				
				gBrush.setColor(default_graph_configuration->colors.transpRed);
				posy=box.GRAPHOY+box.GRAPHHEIGHT-(low-FCminDisplay)*propy;
				height=-(up-low)*propy;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			else if (exo->p[*rit].guidetype==0x18) //sportzone
			{
				int sz=(int)exo->p[*rit].FClow[0];
				if (sz>=0 && sz<=4)
				{
					float minfc,maxfc;
					minfc=sportzone[4-sz]*FCmaxDisplay/100.;
					maxfc=sportzone[4-sz+1]*FCmaxDisplay/100.;
				checkBounds(minfc,FCminDisplay,FCmaxDisplay);
				checkBounds(maxfc,FCminDisplay,FCmaxDisplay);

					gBrush.setColor(default_graph_configuration->colors.transpRed);
					posy=box.GRAPHOY+box.GRAPHHEIGHT-(minfc-FCminDisplay)*propy;
					height=-(maxfc-minfc)*propy;
					scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
				}
			}
			else if (exo->p[*rit].guidetype==0x15) //HR percents
			{
				float minfc=exo->p[*rit].FClow[0]*FCmaxDisplay/100.;
				float maxfc=exo->p[*rit].FCHigh[0]*FCmaxDisplay/100.;
				checkBounds(minfc,FCminDisplay,FCmaxDisplay);
				checkBounds(maxfc,FCminDisplay,FCmaxDisplay);
				
				gBrush.setColor(default_graph_configuration->colors.transpRed);
				posy=box.GRAPHOY+box.GRAPHHEIGHT-(minfc-FCminDisplay)*propy;
				height=-(maxfc-minfc)*propy;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			else if (exo->p[*rit].guidetype==0x24) //speed
			{
				hasSpeed=1;
				float minspeed=exo->p[*rit].FClow[1];
				float maxspeed=exo->p[*rit].FCHigh[1];
				checkBounds(minspeed,SPEEDminDisplay,SPEEDmaxDisplay);
				checkBounds(maxspeed,SPEEDminDisplay,SPEEDmaxDisplay);

				gBrush.setColor(default_graph_configuration->colors.transpBlue);
				posy=box.GRAPHOY+box.GRAPHHEIGHT-(minspeed-SPEEDminDisplay)*propy2;
				height=-(maxspeed-minspeed)*propy2;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			else if (exo->p[*rit].guidetype==0x34) //pace
			{
				float valmin = msb_lsb_to_decimal(exo->p[*rit].FClow[1],exo->p[*rit].FClow[0]);
				float valmax = msb_lsb_to_decimal(exo->p[*rit].FCHigh[1],exo->p[*rit].FCHigh[0]);
				valmin=36000.0/valmin;
				valmax=36000.0/valmax;
				checkBounds(valmin,SPEEDminDisplay,SPEEDmaxDisplay);
				checkBounds(valmax,SPEEDminDisplay,SPEEDmaxDisplay);
				
				hasSpeed=1;
				gBrush.setColor(default_graph_configuration->colors.transpBlue);
				posy=box.GRAPHOY+box.GRAPHHEIGHT-(valmin-SPEEDminDisplay)*propy2;
				height=-(valmax-valmin)*propy2;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);	
			}
			else if (exo->p[*rit].guidetype==0x04) //free
			{
				gBrush.setColor(default_graph_configuration->colors.transpWhite);
				posy=box.GRAPHOY;
				height=box.GRAPHHEIGHT;
				scene->addRect(shiftx,posy,propX*duration,height,gPen,gBrush);
			}
			shiftx+=propX*duration+5;
		}
	}
	drawAxes();
}


void advExoGraph::drawAxes()
{
	drawAxisLeft (QObject::tr("HR [bpm]"),Qt::red,BASE10AXIS,FCminDisplay,FCmaxDisplay);
	if (hasSpeed==1) drawAxisRight(QObject::tr("speed(km/h)"),Qt::blue,BASE10AXIS,SPEEDminDisplay,SPEEDmaxDisplay);
	if (hasTime!=0) drawAxisBottom(QObject::tr("time"), Qt::black, BASE60AXIS, 0.0, totalTime);
}

void yearStatsGraph::plot()
{
	initializeAxesScales(); //calls graph:: default configuration
	QPen gPen;
	QBrush gBrush;

	gPen.setColor(Qt::black);
	gBrush.setStyle(Qt::NoBrush);
	gBrush.setColor(default_graph_configuration->colors.c0);

	qDeleteAll( scene->items() );
	drawGraphPaperBG();
	scene->addRect(box.GRAPHOX,box.GRAPHOY,box.GRAPHWIDTH,box.GRAPHHEIGHT);
	
	
	if (type==0) drawAccumulatedTime();
	else if (type==1) drawStartTimes();
	else if (type==2) drawDurations();
	else if (type==3) drawHRates();

	drawLegends();
}

void yearStatsGraph::drawAccumulatedTime()
{
	QPen gPen;
	QBrush gBrush;

	gPen.setColor(Qt::black);
	gBrush.setStyle(Qt::SolidPattern);
	
	int height0=box.GRAPHHEIGHT;
	int nbbars=SportzoneBars.size();
	if (nbbars==0) return;
	float width0=box.GRAPHWIDTH/(float)nbbars;
	
	//for hr display:
	float rangeY = (FCmaxDisplay-FCminDisplay)/box.GRAPHHEIGHT;
	//QPolygonF polygon;
	std::vector<QPointF> polygon;
	//polygon<<QPointF(0,GRAPHHEIGHT);
	

	for (unsigned int i=0;i<SportzoneBars.size();i++)
	{
		if (SportzoneBars[i].weekTime!=0)
		{
			//1) bars
			int totaltaille=(SportzoneBars[i].weekTime/(float)maxtimeWeek)*height0;

			int lastY=height0+box.GRAPHOY;
			gBrush.setColor(default_graph_configuration->colors.c0);
			float frac=SportzoneBars[i].timeInZones[5]/(float)SportzoneBars[i].weekTime;
			scene->addRect(i*width0+box.GRAPHOX,lastY,width0,-totaltaille*frac,gPen,gBrush);
			lastY-=totaltaille*frac-1; if (frac==0) lastY-=1;

			gBrush.setColor(default_graph_configuration->colors.c1);
			frac=SportzoneBars[i].timeInZones[4]/(float)SportzoneBars[i].weekTime;
			scene->addRect(i*width0+box.GRAPHOX,lastY,width0,-totaltaille*frac,gPen,gBrush);
			lastY-=totaltaille*frac-1; if (frac==0) lastY-=1;

			gBrush.setColor(default_graph_configuration->colors.c2);
			frac=SportzoneBars[i].timeInZones[3]/(float)SportzoneBars[i].weekTime;
			scene->addRect(i*width0+box.GRAPHOX,lastY,width0,-totaltaille*frac,gPen,gBrush);
			lastY-=totaltaille*frac-1; if (frac==0) lastY-=1;

			gBrush.setColor(default_graph_configuration->colors.c3);
			frac=SportzoneBars[i].timeInZones[2]/(float)SportzoneBars[i].weekTime;
			scene->addRect(i*width0+box.GRAPHOX,lastY,width0,-totaltaille*frac,gPen,gBrush);
			lastY-=totaltaille*frac-1; if (frac==0) lastY-=1;

			gBrush.setColor(default_graph_configuration->colors.c4);
			frac=SportzoneBars[i].timeInZones[1]/(float)SportzoneBars[i].weekTime;
			scene->addRect(i*width0+box.GRAPHOX,lastY,width0,-totaltaille*frac,gPen,gBrush);
			lastY-=totaltaille*frac-1; if (frac==0) lastY-=1;

			gBrush.setColor(default_graph_configuration->colors.c5);
			frac=SportzoneBars[i].timeInZones[0]/(float)SportzoneBars[i].weekTime;
			scene->addRect(i*width0+box.GRAPHOX,lastY,width0,-totaltaille*frac,gPen,gBrush);
			lastY-=totaltaille*frac-1; if (frac==0) lastY-=1;
			
			//2)hr
		float tmp = HRaverages[i];
		//data correction for plot: don't go away from the screen
		if (tmp > FCmaxDisplay) tmp=FCmaxDisplay;
		if (tmp < FCminDisplay) tmp=FCminDisplay;
		if (tmp!=0) polygon.push_back(QPointF( i*width0+width0/2.0+box.GRAPHOX,box.GRAPHHEIGHT-(tmp-FCminDisplay)/rangeY));
		}
	}

	gPen.setColor(Qt::red);
	gPen.setWidth(2);
	gBrush.setStyle(Qt::NoBrush);
	gBrush.setColor(default_graph_configuration->colors.transpWhite);

	if (polygon.size()>=2)
	{
		for (unsigned int i=0;i<polygon.size()-1;i++)
		{
			QLineF tmp(polygon[i],polygon[i+1]);
			scene->addLine(tmp,gPen);
		}
	}

	drawAxisRight(QObject::tr("Accumulated time"), Qt::black, BASE60AXIS,0.0, maxtimeWeek);
	drawAxisLeft(QObject::tr("HR [bpm]"), Qt::red, BASE10AXIS, FCminDisplay, FCmaxDisplay);
	drawAxisYear(QObject::tr(""), Qt::black);
}


void yearStatsGraph::drawLegends()
{
	char duration[10],duration2[10],duration3[10];

	timetostr(duration, totalTime);
	QString tottime=QString(duration);

	timetostr(duration2, averageTime);
	QString avtime=QString(duration2);

	timetostr(duration3, averageStartTime);
	QString avStart=QString(duration3);
	
	scene->addText( QObject::tr("Number of exercises: ")+QString::number(NumExercises),box.myfont)->setPos(box.LEGEND1_OX ,box.LEGEND1_OY);
	scene->addText( QObject::tr("Total time: ")+tottime,box.myfont)->setPos(box.LEGEND1_OX ,box.LEGEND1_OY+20*box.ratio2normal);
	scene->addText( QObject::tr("Total calories: ")+QString::number(totalCalories),box.myfont)-> setPos(box.LEGEND1_OX ,box.LEGEND1_OY+40*box.ratio2normal);
}

void yearStatsGraph::drawStartTimes()
{
	QPen pinceau(Qt::black,1);
	QBrush brosse0;

	brosse0.setStyle(Qt::SolidPattern);
	brosse0.setColor(default_graph_configuration->colors.c0);
	
	int height0=box.GRAPHHEIGHT;
	int nbbars=startTimes.size();
	if (nbbars==0) return;
	float width0=box.GRAPHWIDTH/(float)nbbars;
	int lastY=height0+box.GRAPHOY;
	
	for (unsigned int i=0;i<startTimes.size();i++)
	{
		scene->addRect(QRectF(i*width0+box.GRAPHOX,lastY,width0, -startTimes[i]*height0),pinceau,brosse0);
	}
	drawAxisLeft(QObject::tr("PSF"), Qt::red, BASE10AXIS, 0, 1);
	drawAxisBottom(QObject::tr("Hour"), Qt::black, BASE60AXIS, 0, 24*3600);
}


void yearStatsGraph::drawDurations()
{
	QPen pinceau(Qt::black,1);
	QBrush brosse0;

	brosse0.setStyle(Qt::SolidPattern);
	brosse0.setColor(default_graph_configuration->colors.c0);
	
	int height0=box.GRAPHHEIGHT;
	int nbbars=durations.size();
	if (nbbars==0) return;
	float width0=box.GRAPHWIDTH/(float)nbbars;
	int lastY=height0+box.GRAPHOY;
	
	for (unsigned int i=0;i<durations.size();i++)
	{
		scene->addRect(QRectF(i*width0+box.GRAPHOX,lastY,width0, -durations[i]*height0),pinceau,brosse0);
	}
	drawAxisLeft(QObject::tr("PSF"), Qt::red, BASE10AXIS, 0, 1);
	drawAxisBottom(QObject::tr("Duration"), Qt::black, BASE60AXIS, 0, 10*3600);
}


void yearStatsGraph::drawHRates()
{
	QPen pinceau(Qt::black,1);
	QBrush brosse0;

	brosse0.setStyle(Qt::SolidPattern);
	brosse0.setColor(default_graph_configuration->colors.c0);
	
	int height0=box.GRAPHHEIGHT;
	int nbbars=HRates.size();
	if (nbbars==0) return;
	float width0=box.GRAPHWIDTH/(float)nbbars;
	int lastY=height0+box.GRAPHOY;
	
	for (unsigned int i=0;i<HRates.size();i++)
	{
		scene->addRect(QRectF(i*width0+box.GRAPHOX,lastY,width0, -HRates[i]*height0),pinceau,brosse0);
	}
	drawAxisLeft(QObject::tr("PSF"), Qt::red, BASE10AXIS, 0, 1);
	drawAxisBottom(QObject::tr("HRate"), Qt::black, BASE10AXIS, 0, user_hr_max);
}


void yearStatsGraph::drawAxisYear(QString Legend, QColor LegendColor)
{
	int nbstepsH = 10;
	int range=SportzoneBars.size();

	float steptime = gimmeStepTime(range,nbstepsH);
{
//draw horizontal axis
	QGraphicsTextItem * ttt = scene->addText( Legend,box.myfont );
	ttt -> setPos(box.GRAPHWIDTH+10*box.ratio2normal+box.GRAPHOX,box.GRAPHHEIGHT-10*box.ratio2normal+box.GRAPHOY);
	ttt -> setDefaultTextColor(LegendColor);
	
	int i=0;
	while (i*steptime<range && i<=2*nbstepsH)
	{
		scene->addLine(i*steptime/range*box.GRAPHWIDTH,box.GRAPHHEIGHT-3,i*steptime/range*box.GRAPHWIDTH,box.GRAPHHEIGHT+3)->moveBy(box.GRAPHOX,box.GRAPHOY);
		QDate tmp=startDate.addDays(7*i*steptime);

		QString disp = tmp.toString(QString("dd/MM/yy"));

		scene->addText( disp,box.myfont ) -> setPos(i*steptime/range*box.GRAPHWIDTH+box.GRAPHOX,box.GRAPHHEIGHT+10*box.ratio2normal+box.GRAPHOY);
		i++;
	}
}
}
